package com.fq.wechat.filter;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.utils.AddrUtil;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.concurrent.TimeoutException;

/**
 * @author jifang.
 * @since 2016/5/21 15:50.
 */
public class MemcachedFilter implements Filter {

    private MemcachedClient memcached;

    private static final int _1MIN = 60;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        try {
            MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses("139.129.9.166:11211"));
            memcached = builder.build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        // 对PrintWriter包装
        MemcachedWriter mWriter = new MemcachedWriter(response.getWriter());
        chain.doFilter(req, new MemcachedResponse((HttpServletResponse) response, mWriter));

        HttpServletRequest request = (HttpServletRequest) req;
        String key = request.getRequestURI();

        Enumeration<String> names = request.getParameterNames();
        if (names.hasMoreElements()) {
            String name = names.nextElement();
            StringBuilder sb = new StringBuilder(key)
                    .append("?").append(name).append("=").append(request.getParameter(name));
            while (names.hasMoreElements()) {
                name = names.nextElement();
                sb.append("&").append(name).append("=").append(request.getParameter(name));
            }
            key = sb.toString();
        }

        try {
            String rspContent = mWriter.getRspContent() + "<hr/>From Memcached";
            memcached.set(key, _1MIN, rspContent);
        } catch (TimeoutException | InterruptedException | MemcachedException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void destroy() {
    }


    private static class MemcachedWriter extends PrintWriter {

        private StringBuilder sb = new StringBuilder();

        private PrintWriter writer;

        public MemcachedWriter(PrintWriter out) {
            super(out);
            this.writer = out;
        }

        @Override
        public void print(String s) {
            sb.append(s);
            this.writer.print(s);
        }

        public String getRspContent() {
            return sb.toString();
        }
    }

    private static class MemcachedResponse extends HttpServletResponseWrapper {

        private PrintWriter writer;

        public MemcachedResponse(HttpServletResponse response, PrintWriter writer) {
            super(response);
            this.writer = writer;
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return this.writer;
        }
    }
}
